#ifndef __TCP_ECHO_SERVER_HPP__
#define __TCP_ECHO_SERVER_HPP__

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "Comm.hpp"
#include "Logger.hpp"

static const int gdefaultfd = -1;
static const int gbacklog=8;
static const uint16_t gport=8080;

class TcpEchoServer
{
public:
    TcpEchoServer(uint16_t port = gport)
    :_port(port)
    {}

    void Init()
    { 
        //1.create socket
        _listensockfd=socket(AF_INET,SOCK_STREAM,0);
        if(_listensockfd<0)
        {
            LOG(LogLevel::FATAL)<<"creat tcp _listensockfd error";
            exit(SOCKET_CREAT_ERR);
        }
        LOG(LogLevel::INFO)<<"creat tcp _listensockfd seuccess: "<<_listensockfd;
        
        //2. bind socket
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(_port);
        local.sin_addr.s_addr=htonl(INADDR_ANY);

        if(bind(_listensockfd,(struct sockaddr*) &local,sizeof(local))!=0)
        {
            LOG(LogLevel::FATAL)<<"bind _listensockfd error";
            exit(SOCKET_BIND_ERR);
        }
        LOG(LogLevel::INFO)<<"bind _listensockfd success"<<_listensockfd;
        
        //3.listen socket
        //可以用netstat -tlnp命令查看

        if(listen(_listensockfd,gbacklog)!=0)
        {
            LOG(LogLevel::FATAL)<<"listen _listensockfd error";
            exit(SOCKET_LISTEN_ERR);
        }
        LOG(LogLevel::INFO)<<"listen _listensockfd success";  
    }
    void Start()
    {
        while(true)
        {
            struct sockaddr_in peer; 
            socklen_t len=sizeof(peer);
            int socketfd=accept(_listensockfd,(struct sockaddr*)&peer,&len);

            if(socketfd<0)
            {
                LOG(LogLevel::WARNING)<<"accept client error";
                continue;
            }
        }
    }

private:
    int _listensockfd;//监听套接字
    uint16_t _port;
};

#endif